import com.yp.lession.dao.proxy.FangDongImpl;
import com.yp.lession.dao.proxy.NongFuSanQuan;
import org.junit.Test;
import com.yp.lession.dao.proxy.FangDongImpl2;
import com.yp.lession.dao.proxy.ZuFang;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 动态代理的目的,生成一个代理类,来完成核心和辅助功能  帮我们处理事务 日志 等辅助功能
 */

public class InvocationProxyDemo {
    @Test
    public void jdk(){
        //1 目标对象
        FangDongImpl zf = new FangDongImpl();

        //2 Invocationhandler 设置代理类的核心业务 和辅助功能
        InvocationHandler handler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //                             method代理的方法对象     args方法参数
                System.out.println("某房源");
                System.out.println("看某房源");
                //调用目标对象的方法 通过反射来调用目标对象的核心功能方法  这是核心业务
                Object invoke = method.invoke(zf, args);
                return invoke;
            }
        };

        //3 com.yp.lession.dao.proxy 类来动态创建对应的代理类
        ZuFang z = (ZuFang) Proxy.newProxyInstance(
                InvocationProxyDemo.class.getClassLoader(),//代理类本身的类加载器
                zf.getClass().getInterfaces(),//约束生成出来的代理类方法,提供接口信息,
                                                // 让代理类和目标同时实现接口,利用多态使用接口接受代理类的实例,来调用方法
                handler);//添加上辅助功能和调用核心业务的Hanbler

        //4 运行执行
        z.zuFang();

    }
       @Test
    public void ti(){
//        FangDongImpl zf = new FangDongImpl();
//        for (Class<?> anInterface : zf.getClass().getInterfaces()) {
//            for (Method method : anInterface.getMethods()) {
//                System.out.println(method.getName());
//            }
//            Method zf1 = zf.getClass().getMethod("zf");
//            zf1.invoke(zf);
//        }
//
    }

    public  Object proxy(String path) throws Exception {
        Class<?> aClass = Class.forName(path);
        Object c = aClass.newInstance();
        InvocationHandler handler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //辅助功能 按道理来说是可以没有的
                System.out.println("街上拉人看房,介绍半天结果人家是来相亲的");
                //核心任务
                Object invoke = method.invoke(c, args);
                return invoke;
            }
        };
        //3 proxy类 动态创建代理类
        Object o = Proxy.newProxyInstance(InvocationProxyDemo.class.getClassLoader(), aClass.getInterfaces(), handler);
        return o;
    }
    @Test
    public void testProxy() throws Exception {
        //第一个房东
        ZuFang proxy1 = (ZuFang) proxy("com.yp.lession.dao.proxy.FangDongImpl");
        proxy1.zuFang();
        System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~分割表示一下~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
        //第二个房东
       ZuFang proxy2 = (ZuFang) proxy("com.yp.lession.dao.proxy.FangDongImpl2");
       proxy2.zuFang();
        System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~分割表示两下~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
        NongFuSanQuan proxy3 = (NongFuSanQuan) proxy("com.yp.lession.dao.proxy.ShuiChang");
        proxy3.maiShui();
    }


}
